home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Development / MosaicSRC / src / Boingtransfer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-13  |  15.0 KB  |  538 lines

  1. /*
  2. ** BoingTransfer - A MUI Custom Class
  3. ** © 1995, Ruediger Sopp
  4. ** displays a rotating boing ball
  5. ** $VER: BoingTransferClass 1.5 (19.03.95)
  6. */
  7.  
  8. #define WINKELFAKTOR (0.4)
  9.  
  10. #define VERTMOVE (16)
  11. #define VERTMIDPOS (6)
  12.  
  13. //#define AlignValue(a) (16*(a%16?(a/16)+1:a/16))
  14.  
  15. #define AlignValue(a) 160
  16.  
  17. #define RESET_ANIM data->Position=-1;data->LeftDirection=FALSE;data->HorizPos=-10;data->VertPos=VERTMIDPOS;
  18.  
  19. #include "BoingTransfer.h"
  20.  
  21. extern struct ExecBase *SysBase;
  22.  
  23. /// Global stuff
  24. /* These are some sin-/cos-tables to improve rendering speed */
  25.  
  26. double XSinTab[36]={0.00000000000000,-0.19509032201613,-0.38268343236509,-0.55557023301960,-0.70710678118655,-0.83146961230255,-0.92387953251129,-0.98078528040323,-1.00000000000000,-0.98078528040323,-0.92387953251129,-0.83146961230254,-0.70710678118655,-0.55557023301960,-0.38268343236509,-0.19509032201613,-0.00000000000000,0.19509032201613,0.38268343236509,0.55557023301960,0.70710678118655,0.83146961230255,0.92387953251129,0.98078528040323,1.00000000000000,0.98078528040323,0.92387953251129,0.83146961230255,0.70710678118655,0.55557023301960,0.38268343236509,0.19509032201613,0.00000000000000,-0.19509032201613,-0.38268343236509,-0.55557023301960};
  27. double YCosTab[9]={0,0.3826834,0.7071067,0.9238795,1,0.9238795,0.7071067,0.3826834,0};
  28. double YSinTab[9]={-1,-0.8938794,-0.7071067,-0.3826834,0,0.3826834,0.7071067,0.9238795,1};
  29. double VertMoveTab[16]={0.000000,0.019215,0.076120,0.168530,0.292893,0.444430,0.617317,0.804910,1.000000,0.804910,0.617317,0.444430,0.292893,0.168530,0.076120,0.019215,};
  30.  
  31. struct BoingTransferMessage
  32. {
  33.   struct Message ExecMessage;
  34.   ULONG Action;
  35.   APTR App,Class;
  36. };
  37. ///
  38. ///SendChildTaskAction
  39. void SendChildTaskAction(struct BoingTransferClData *data,Object *obj,ULONG Action)
  40. {
  41.   APTR app;
  42.   char PortName[30];      
  43.   struct BoingTransferMessage MsgSend;
  44.   struct MsgPort *ChildPort,*ReplyPort;
  45.  
  46.   sprintf(PortName,"BoingPort.%x",data->AutoMoveProc);
  47.   if(ReplyPort=CreateMsgPort())
  48.   {
  49.     get(obj,MUIA_ApplicationObject,&app);
  50.     ReplyPort->mp_Node.ln_Pri=0;
  51.     ReplyPort->mp_Node.ln_Name="BoingReplyPort";
  52.     ReplyPort->mp_SigTask=(APTR)FindTask(0);
  53.     AddPort(ReplyPort);
  54.     MsgSend.ExecMessage.mn_Length=sizeof(struct Message);
  55.     MsgSend.ExecMessage.mn_Node.ln_Type=NT_MESSAGE;
  56.     MsgSend.ExecMessage.mn_ReplyPort=ReplyPort;
  57.     MsgSend.Action=Action;
  58.     MsgSend.App=app;
  59.     MsgSend.Class=obj;
  60.     Forbid();
  61.     if(ChildPort=(struct MsgPort *)FindPort(PortName))
  62.     {
  63.       PutMsg(ChildPort,(struct Message *)&MsgSend);
  64.     }
  65.     Permit();
  66.     WaitPort(ReplyPort);
  67.     RemPort(ReplyPort);
  68.     DeletePort(ReplyPort);
  69.   }
  70. }       
  71. ///
  72. ///AutoMove
  73. static void __saveds AutoMove(void)
  74. {
  75.   APTR App,Obj;
  76.   char PortName[30];
  77.   struct MsgPort *Port;
  78.  
  79.   sprintf(PortName,"BoingPort.%x",SysBase->ThisTask);
  80.   if(Port=CreateMsgPort())
  81.   {
  82.     BOOL running=TRUE;
  83.     struct BoingTransferMessage *Msg;
  84.     Port->mp_Node.ln_Pri=0;
  85.     Port->mp_Node.ln_Name=PortName;
  86.     Port->mp_SigTask=(APTR)FindTask(0);
  87.     AddPort(Port);
  88.     WaitPort(Port);
  89.     while(Msg=(struct BoingTransferMessage *)GetMsg(Port))
  90.     {
  91.       App=Msg->App;
  92.       Obj=Msg->Class;
  93.       ReplyMsg((struct Message *)Msg);
  94.     }     
  95.     while(running)
  96.     {
  97.       DoMethod(App,MUIM_Application_PushMethod,Obj,1,MUIM_BoingTransfer_Move);
  98.       DoMethod(App,MUIM_Application_PushMethod,App,1,MUIM_Application_InputBuffered);
  99.       Delay(6);
  100.       while(Msg=(struct BoingTransferMessage *)GetMsg(Port))
  101.       {
  102.         running=FALSE;
  103.         ReplyMsg((struct Message *)Msg);
  104.       }
  105.     }
  106.     RemPort(Port);
  107.     DeletePort(Port);
  108.   }
  109. }     
  110. ///
  111. ///CreateAutoMoveProc
  112. void CreateAutoMoveProc(struct BoingTransferClData *data,Object *obj)
  113. {
  114.   char PortName[30];
  115.   if(!data->AutoMoveProc)
  116.   {
  117.     if(data->AutoMoveProc=CreateNewProcTags(NP_Entry,AutoMove,NP_Name,"BoingMover",NP_Priority,-1,TAG_DONE))
  118.     {
  119.       sprintf(PortName,"BoingPort.%x",data->AutoMoveProc);
  120.       while(!FindPort(PortName))
  121.         Delay(1);
  122.       SendChildTaskAction(data,obj,0);
  123.     }
  124.   }
  125. }
  126. ///
  127. ///BreakAutoMoveProc
  128. void BreakAutoMoveProc(struct BoingTransferClData *data,Object *obj)
  129. {
  130.   if(data->AutoMoveProc)
  131.   {
  132.     SendChildTaskAction(data,obj,0);
  133.     data->AutoMoveProc=NULL;
  134.   }
  135. }
  136. ///
  137. ///FreeBitMaps
  138. void FreeBitMaps(struct BoingTransferClData *data)
  139. {
  140.   long i;
  141.   WaitBlit();
  142.   for(i=0;i<FRAMES;i++)
  143.   {
  144.     FreeBitMap(data->BitMap[i]);
  145.     data->BitMap[i]=NULL;
  146.   }
  147.   FreeBitMap(data->Mask);
  148.   data->Mask=NULL;
  149.   if(data->Bitplane)
  150.   {
  151.     FreeRaster(data->Bitplane,AlignValue(data->BitMapSize),AlignValue(data->BitMapSize));
  152.     data->Bitplane=NULL;
  153.   }    
  154. }
  155. ///
  156. ///InitBitMaps
  157. BOOL InitBitMaps(Object *obj,struct BoingTransferClData *data)
  158. {
  159.   ULONG i;
  160.   FreeBitMaps(data);   
  161.   data->BitMapSize=2*data->Radius+4;
  162.   if(data->Bitplane=AllocRaster(AlignValue(data->BitMapSize),AlignValue(data->BitMapSize)))
  163.   {
  164.     InitTmpRas(&data->TmpRaster,data->Bitplane,RASSIZE(AlignValue(data->BitMapSize),AlignValue(data->BitMapSize)));
  165.     InitArea(&data->AInfo,data->Buffer,10);
  166.     if(data->Mask=AllocBitMap(data->BitMapSize,data->BitMapSize,1,NULL,NULL))
  167.     {
  168.       InitRastPort(&data->MaskRP);
  169.       data->MaskRP.BitMap=data->Mask;
  170.       data->MaskRP.TmpRas=&data->TmpRaster;
  171.       data->MaskRP.AreaInfo=&data->AInfo;         
  172.  
  173.       InitRastPort(&data->BackRP);
  174.  
  175.       for(i=0;i<FRAMES;i++)
  176.       {
  177.         if(data->BitMap[i]=AllocBitMap(data->BitMapSize,data->BitMapSize,_screen(obj)->RastPort.BitMap->Depth,NULL,NULL))
  178.         {
  179.           InitRastPort(&data->RP[i]);
  180.           data->RP[i].BitMap=data->BitMap[i];
  181.           data->RP[i].TmpRas=&data->TmpRaster;
  182.           data->RP[i].AreaInfo=&data->AInfo;         
  183.         }
  184.         else
  185.           return(FALSE);
  186.       }
  187.     }
  188.     else
  189.       return(FALSE);
  190.   }
  191.   else
  192.     return(FALSE);
  193.   return(TRUE);
  194. }
  195. ///
  196. ///GetXYPos: turn 3d coordinates into 2d coordinates
  197. void __inline __regargs GetXYPos(double Offset,long x,long y,double Radius,long *ResX,long *ResY)
  198. {
  199.   double rx,ry;
  200.   double XAbstand=XSinTab[x]*Radius*YCosTab[y],YAbstand=YSinTab[y]*(double)Radius;
  201.  
  202. //  double XAbstand=sin(x*PI/16+PID2)*Radius*YCosTab[y],YAbstand=YSinTab[y]*(double)Radius;
  203.  
  204.   rx=Offset+XAbstand-YAbstand*WINKELFAKTOR;
  205.   ry=Offset+YAbstand+XAbstand*WINKELFAKTOR;
  206.   *ResX=rx;
  207.   *ResY=ry;
  208. }
  209. ///
  210. ///DrawBoingBall
  211. void __inline DrawBoingBall(struct RastPort *RP,double Radius,struct BoingTransferClData *data,Object *obj,long WinkelOffset,long RedPen,long WhitePen)
  212. {
  213.   long x,y,xw,ResX,ResY;
  214.   for(x=0;x<16;x++)
  215.   {
  216.     xw=x*2+WinkelOffset;
  217.     if(xw+2>24||xw<8)
  218.     {
  219.       for(y=0;y<8;y++)
  220.       {            
  221.         SetAPen(RP,(y+x)/2*2==(y+x)?RedPen:WhitePen);
  222.  
  223.         GetXYPos(Radius,xw,y,Radius,&ResX,&ResY);
  224.         AreaMove(RP,ResX,ResY);
  225.  
  226.         GetXYPos(Radius,xw+2,y,Radius,&ResX,&ResY);
  227.         AreaDraw(RP,ResX,ResY);
  228.  
  229.         GetXYPos(Radius,xw+2,y+1,Radius,&ResX,&ResY);
  230.         AreaDraw(RP,ResX,ResY);
  231.  
  232.         GetXYPos(Radius,xw,y+1,Radius,&ResX,&ResY);
  233.         AreaDraw(RP,ResX,ResY);
  234.  
  235.         AreaEnd(RP);
  236.       }
  237.     }
  238.   }
  239. }
  240. ///
  241. ///CalculateBoingBall: render the frames of the animation
  242. void __regargs CalculateBoingBall(struct BoingTransferClData *data,Object *obj)
  243. {
  244.   long i;
  245.  
  246.   if(InitBitMaps(obj,data))
  247.   {
  248.     SetAPen(&data->MaskRP,0);
  249.     RectFill(&data->MaskRP,0,0,2*(ULONG)data->Radius,2*(ULONG)data->Radius);
  250.     SetAPen(&data->MaskRP,1);
  251.     AreaEllipse(&data->MaskRP,(long)data->Radius,(long)data->Radius,(long)data->Radius,(long)data->Radius);
  252.     AreaEnd(&data->MaskRP);
  253.  
  254.     for(i=0;i<FRAMES;i++)
  255.       DrawBoingBall(&data->RP[i],data->Radius,data,obj,i,data->RedPen,data->WhitePen);
  256.   }
  257.   else
  258.     FreeBitMaps(data);
  259. }
  260. ///
  261. ///BoingTransferAskMinMax
  262. __saveds static ULONG BoingTransferAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg)
  263. {
  264.   DoSuperMethodA(cl,obj,(Msg)msg);
  265.  
  266.   msg->MinMaxInfo->MinWidth  += 30;
  267.   msg->MinMaxInfo->DefWidth  += 50;
  268.   msg->MinMaxInfo->MaxWidth  += 80; // 110;
  269.  
  270.   msg->MinMaxInfo->MinHeight += 30;
  271.   msg->MinMaxInfo->DefHeight += 50;
  272.   msg->MinMaxInfo->MaxHeight += 64; // 110;
  273.  
  274.   return(0);
  275. }
  276. ///
  277. ///BoingTransferSetup
  278. __saveds static ULONG BoingTransferSetup(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  279. {
  280.   struct BoingTransferClData *data = INST_DATA(cl,obj);
  281.   if(!(DoSuperMethodA(cl,obj,(Msg)msg)))
  282.     return(FALSE);
  283.  
  284.   data->RedPen=ObtainBestPen(_screen(obj)->ViewPort.ColorMap,0xff<<24,0,0,TAG_DONE);
  285.   if(data->RedPen!=-1)
  286.   {
  287.     data->WhitePen=ObtainBestPen(_screen(obj)->ViewPort.ColorMap,0xff<<24,0xff<<24,0xff<<24,TAG_DONE);
  288.     if(data->WhitePen!=-1)
  289.     {
  290.       RESET_ANIM;
  291.       return(TRUE);
  292.     }
  293.     ReleasePen(_screen(obj)->ViewPort.ColorMap,data->RedPen);
  294.   }
  295.   return(FALSE);
  296. }
  297. ///
  298. ///BoingTransferCleanup
  299. __saveds static ULONG BoingTransferCleanup(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  300. {
  301.   struct BoingTransferClData *data = INST_DATA(cl,obj);
  302.  
  303.   if(data->RedPen!=-1)
  304.     ReleasePen(_screen(obj)->ViewPort.ColorMap,data->RedPen); 
  305.   if(data->WhitePen!=-1)
  306.     ReleasePen(_screen(obj)->ViewPort.ColorMap,data->WhitePen);
  307.   data->RedPen=data->WhitePen=-1;
  308.  
  309.   FreeBitMaps(data);
  310.  
  311.   data->Radius=0;
  312.  
  313.   return(DoSuperMethodA(cl,obj,(Msg)msg));
  314. }
  315. ///
  316. ///BoingTransferShow
  317. __saveds static ULONG BoingTransferShow(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  318. {
  319.   struct BoingTransferClData *data = INST_DATA(cl,obj);
  320.   if(!(DoSuperMethodA(cl,obj,(Msg)msg)))
  321.     return(FALSE);
  322.  
  323.   if(data->Temp=AllocBitMap(_mwidth(obj),_mheight(obj),_screen(obj)->RastPort.BitMap->Depth,BMF_INTERLEAVED,_rp(obj)->BitMap))
  324.   {
  325.     InitRastPort(&data->TempRP);
  326.     data->TempRP.BitMap=data->Temp;  
  327.     if(data->AutoMove)
  328.     {
  329.       CreateAutoMoveProc(data,obj);
  330.     }
  331.  
  332.     return(TRUE);
  333.   }       
  334.  
  335.   return(FALSE);
  336. }
  337. ///
  338. ///BoingTransferHide
  339. __saveds  ULONG BoingTransferHide(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  340. {
  341.   struct BoingTransferClData *data = INST_DATA(cl,obj);
  342.  
  343.   BreakAutoMoveProc(data,obj);
  344.  
  345.   WaitBlit();
  346.   FreeBitMap(data->Temp);
  347.   data->Temp=NULL;
  348.   FreeBitMap(data->Back);
  349.   data->Back=NULL;
  350.  
  351.   return(DoSuperMethodA(cl,obj,(Msg)msg));
  352. }
  353. ///  
  354. /// BoingTransferSet
  355. __saveds static ULONG BoingTransferSet(struct IClass *cl,Object *obj,Msg msg)
  356. {
  357.   struct BoingTransferClData *data = INST_DATA(cl,obj);
  358.   struct TagItem *tags,*tag;
  359.  
  360.   for (tags=((struct opSet *)msg)->ops_AttrList;tag=NextTagItem(&tags);)
  361.   {
  362.     switch (tag->ti_Tag)
  363.     {
  364.       case MUIA_BoingTransfer_AutoMove:
  365.         if(tag->ti_Data)
  366.         {
  367.           data->AutoMove=TRUE;
  368.           CreateAutoMoveProc(data,obj);
  369.         }
  370.         else
  371.         {
  372.           data->AutoMove=FALSE;
  373.           BreakAutoMoveProc(data,obj);
  374.         }
  375.         break;
  376.     }
  377.   }
  378.  
  379.   return(DoSuperMethodA(cl,obj,msg));
  380. ///
  381. ///BoingTransferDraw
  382. __saveds static ULONG BoingTransferDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
  383. {
  384.   long LeftEdge,TopEdge,Frame;
  385.   struct BoingTransferClData *data = INST_DATA(cl,obj);
  386.   DoSuperMethodA(cl,obj,(Msg)msg);
  387.  
  388.   if(msg->flags&MADF_DRAWOBJECT)
  389.   {
  390.     if(data->Temp)
  391.     {
  392.       double Radius;
  393.       Radius=min(_mwidth(obj),_mheight(obj))/2.7;
  394.       if(data->HorizPos>_mwidth(obj)-1-2*(long)Radius)
  395.         data->HorizPos=_mwidth(obj)-1-2*(long)Radius;
  396.       if(data->Radius!=Radius)
  397.       {
  398.         data->Radius=Radius;
  399.         CalculateBoingBall(data,obj);
  400.       }
  401.       if(data->BitMap[FRAMES-1])
  402.       {
  403.         FreeBitMap(data->Back);
  404.         data->Back=NULL;
  405.         if(data->Back=AllocBitMap(_mwidth(obj),_mheight(obj),_screen(obj)->RastPort.BitMap->Depth,NULL,NULL))
  406.         {
  407.           data->BackRP.BitMap=data->Back;
  408.           ClipBlit(_rp(obj),_mleft(obj),_mtop(obj),&data->BackRP,0,0,_mwidth(obj),_mheight(obj),0xc0);
  409.         }
  410.       }
  411.     }
  412.   }
  413.  
  414.   if(data->Position<0)
  415.   {
  416.     LeftEdge=_mwidth(obj)/2-data->Radius;
  417.     TopEdge=_mheight(obj)/2-data->Radius;
  418.     data->HorizPos=_mwidth(obj)/2-data->Radius+1;
  419.     data->Position=1;
  420.     Frame=0;
  421.   }
  422.   else
  423.   {
  424.     LeftEdge=data->HorizPos;
  425.     TopEdge=VertMoveTab[data->VertPos]*(_mheight(obj)-2*data->Radius);
  426.     Frame=data->Position;
  427.   }
  428.  
  429.   if(data->Back)
  430.   {
  431.     BltBitMapRastPort(data->Back,0,0,&data->TempRP,0,0,_mwidth(obj),_mheight(obj),0xc0);
  432.     BltMaskBitMapRastPort(data->BitMap[Frame],0,0,&data->TempRP,LeftEdge,TopEdge,2*(ULONG)data->Radius+1,2*(ULONG)data->Radius+1,0xe0,data->Mask->Planes[0]);
  433.     ClipBlit(&data->TempRP,0,0,_rp(obj),_mleft(obj),_mtop(obj),_mwidth(obj),_mheight(obj),0xc0);
  434.   }
  435.  
  436.   return(0);
  437. }
  438. ///
  439. ///BoingTransferDispatcher
  440. __saveds __asm ULONG BoingTransferDispatcher(register __a0 struct IClass *cl,register __a2 Object *obj,register __a1 Msg msg)
  441. {
  442.   switch(msg->MethodID)
  443.   {
  444.     case MUIM_AskMinMax  : return(BoingTransferAskMinMax  (cl,obj,(APTR)msg));  
  445.     case MUIM_Setup      : return(BoingTransferSetup      (cl,obj,(APTR)msg));
  446.     case MUIM_Cleanup    : return(BoingTransferCleanup    (cl,obj,(APTR)msg));  
  447.     case MUIM_Show       : return(BoingTransferShow       (cl,obj,(APTR)msg));
  448.     case MUIM_Hide       : return(BoingTransferHide       (cl,obj,(APTR)msg));
  449.     case MUIM_Draw       : return(BoingTransferDraw       (cl,obj,(APTR)msg));
  450.     case OM_SET          : return(BoingTransferSet        (cl,obj,(APTR)msg));
  451.     case MUIM_BoingTransfer_Move:
  452.     {
  453.       struct BoingTransferClData *data = INST_DATA(cl,obj);
  454.  
  455.       MUI_Redraw(obj,MADF_DRAWUPDATE);
  456.  
  457.       if(data->LeftDirection)
  458.       {
  459.         data->Position--;
  460.         if(data->Position<0)
  461.           data->Position=FRAMES-1;
  462.         data->HorizPos--;
  463.         if(data->HorizPos<0)
  464.         {
  465.           data->HorizPos=0;
  466.           data->LeftDirection=FALSE;
  467.         }                                        
  468.       }           
  469.       else
  470.       {
  471.         data->Position++;
  472.         if(data->Position>FRAMES-1)
  473.           data->Position=0;
  474.         data->HorizPos++;
  475.         if(data->HorizPos>_mwidth(obj)-2*data->Radius)
  476.         {
  477.           data->HorizPos=_mwidth(obj)-2*data->Radius;
  478.           data->LeftDirection=TRUE;
  479.         }                        
  480.       }                         
  481.  
  482.       data->VertPos++;
  483.       if(data->VertPos>VERTMOVE-1)
  484.         data->VertPos=0;
  485.       return(0);
  486.     }
  487.     case MUIM_BoingTransfer_Reset:
  488.     {
  489.       struct BoingTransferClData *data = INST_DATA(cl,obj);
  490.       RESET_ANIM;
  491.       MUI_Redraw(obj,MADF_DRAWUPDATE);
  492.       return(0);
  493.     }
  494.   }
  495.  
  496.   return(DoSuperMethodA(cl,obj,(Msg)msg));
  497. }
  498. ///
  499.  
  500. ///BoingTransferClInit
  501. // ************************************************************
  502. // Initilize the Boing class
  503. // ************************************************************
  504. Class *BoingTransferClInit(void)
  505. {
  506.   APTR SuperClass;
  507.   Class *cl = NULL;
  508.  
  509.   if (!(SuperClass = MUI_GetClass(MUIC_Area)))
  510.     fail(NULL, "Superclass for Boing class not found.");
  511.  
  512.   if (!(cl = MakeClass(NULL, NULL, SuperClass, sizeof(struct BoingTransferClData), 0)))
  513.     {
  514.       MUI_FreeClass(SuperClass);
  515.       fail(NULL, "Failed to create Boing class.");
  516.     }
  517.  
  518.   cl->cl_Dispatcher.h_Entry = (APTR)BoingTransferDispatcher;
  519.   cl->cl_Dispatcher.h_SubEntry = NULL;
  520.   cl->cl_Dispatcher.h_Data = NULL;
  521.  
  522.   return cl;
  523. }
  524. ///
  525. ///BoingTransferClFree
  526. // *******************************************************
  527. // Free the BoingTransfer class
  528. // IS THERE AN ERROR HERE BECAUSE SUPERCLASS IS NEVER FREED? Yep! (sb)
  529. // *******************************************************
  530. BOOL BoingTransferClFree(Class *cl)
  531. {
  532.   FreeClass(cl);
  533.   return 0;
  534. ///
  535.  
  536.